# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Dockerfile for running a specific benchmark for a specific fuzzer.
#
# This Dockerfile adds essential files into the runner image, regardless of
# whether it was built from `benchmark-runner/Dockerfile` or a custom
# `runner.Dockerfile`.
#
# The benchmark/fuzzer pair is defined by build arguments. To specify them, pass
# the following arguments to docker build:
#
# $ docker build \
#   --build-arg benchmark=afl \
#   --build-arg fuzzer=freetype2-2017 \
#   ...

ARG fuzzer
ARG benchmark

# We use Docker's multi-stage build feature to create a minimal runner image,
# separate from the sometimes bulky builder images.

# We take the already built builder image for the given fuzzer/benchmark pair
# and refer to it as "builder", so we can copy the build artifacts from it.
FROM gcr.io/fuzzbench/builders/$fuzzer/$benchmark AS builder

# We base the runner image from the intermediate runner image, defined by the
# runner.Dockerfile of each fuzzer.
FROM gcr.io/fuzzbench/runners/$fuzzer/$benchmark-intermediate

# Install runtime dependencies for benchmarks.

RUN apt-get update -y && \
    DEBIAN_FRONTEND="noninteractive" apt-get install -y \
    libglib2.0-0 \
    libxml2 \
    libarchive13 \
    libgss3

# Set up the directory for the build artifacts.
ENV OUT /out
ENV WORKDIR /out
RUN mkdir -p $WORKDIR
WORKDIR $WORKDIR

ENV ROOT_DIR=/src

# Copy over all the build artifacts (without * to preserve directory structure).
# This also copies seed and dictionary files if they are available.
COPY --from=builder /out/ ./
# Copy the benchmarks directory.
COPY benchmarks $ROOT_DIR/benchmarks
# Copy the fuzzers directory.
COPY fuzzers $ROOT_DIR/fuzzers

# Define environment variables used when we run the fuzzer:
# - Directory to get starting seeds from.
ENV SEED_CORPUS_DIR=$WORKDIR/seeds
# - Where to place new test cases generated by the fuzzer.
ENV OUTPUT_CORPUS_DIR=$WORKDIR/corpus

# Create the seeds directory if it doesn't exist.
RUN mkdir -p $SEED_CORPUS_DIR $OUTPUT_CORPUS_DIR

# Copy the source code into the image. We do this here instead of in base-image
# because it is likely to change, particularly in development. If this were done
# earlier, build cycles would be intolerably slow.
COPY common $ROOT_DIR/common
COPY experiment/runner.py $ROOT_DIR/experiment/runner.py
COPY docker/benchmark-runner $ROOT_DIR/docker/benchmark-runner

ENV PYTHONPATH=$ROOT_DIR
RUN chmod +x $ROOT_DIR/docker/benchmark-runner/startup-runner.sh
ENTRYPOINT $ROOT_DIR/docker/benchmark-runner/startup-runner.sh
